package com.kaibes.core.base.proxy;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class ProxyHandlerSimple<E> {

    private E target;
    private ProxyInvokeListener invokelistener;

    public ProxyHandlerSimple(E target) {
        this.target = target;
    }

    public void setInvokelistener(ProxyInvokeListener invokelistener) {
        this.invokelistener = invokelistener;
    }

    public E getTarget() {
        return target;
    }

    public Object doMethod(String methodName, Object... args)
            throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        try {
            Method method = getMethod(methodName, args);
            return invoke(target, method, args);
        } catch (NoSuchMethodException | SecurityException e) {
            throw new RuntimeException(e);
        }
    }

    private Object invoke(final Object proxy, final Method method, final Object[] args)
            throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        if (invokelistener == null) {
            return method.invoke(target, args);
        } else {
            boolean flag = invokelistener.beforeInvoke(proxy, method, args);
            Object result = null;
            if (flag) {
                result = invokelistener.doInvoke(method, args, args);
            }
            result = invokelistener.afterInvoke(result);
            return result;
        }
    }

    private Method getMethod(String methodName, Object... args) throws NoSuchMethodException, SecurityException {
        if (args != null && args.length > 0) {
            Class<?>[] parameterTypes = new Class<?>[args.length];
            for (int i = 0; i < parameterTypes.length; i++) {
                parameterTypes[i] = args[i].getClass();
            }
            return target.getClass().getMethod(methodName, parameterTypes);
        } else {
            return target.getClass().getMethod(methodName);
        }
    }

}
